home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Programming / JForth / JTools / Appls / update.f < prev    next >
Encoding:
FORTH Source  |  1992-01-15  |  21.8 KB  |  935 lines

  1. \ (c) 1987 Mike Haas ... 13-may-87 ... UPDATE and UPD
  2. \
  3. \  This JForth program examines the two directories, then copies everything
  4. \  from <srcdir> to <destdir> that meet the specified criteria.
  5. \
  6. \  Usage:
  7. \
  8. \      Update  SourceDir DestDir [-date|-size -list -noask
  9. \                                 -both -all -warn <dd-mm-yy>]
  10. \
  11. \     -date = SourceDir/file is later than DestDir/file (default)
  12. \     -size = SourceDir/file is different size than DestDir/file
  13. \     -list = Don't really copy, just list the files that WOULD.
  14. \     -noask= Don't ask the user to verify input
  15. \     -both = Update only those files that exist in BOTH directories
  16. \     -all  = Update all subdirectories also
  17. \     -off  = Turn off ansi highlighting for directory names" cr
  18. \     -warn = Warn if both files are newer than <date> (don't copy)" cr
  19. \
  20. \
  21. \  This program is a boon to those with mucho ram, even with recoverable
  22. \  ram.  It saves constant copying of files from ram: or vd0: to disk every
  23. \  time you edit something.
  24. \
  25. \  You can edit out of ram in a 'duplicate' of your permanent directory on
  26. \  disk...then, with one command, just copy to that dir JUST WHATS DIFFERENT.
  27. \
  28. \
  29. \  ------------------- SPECIAL NOTES IF USED FROM JFORTH (not CLONEd)
  30. \
  31. \  The first time you use UPDATE for a project, use the normal
  32. \  UPDATE SourceDir DestDir [??]  form.  The pathnames are saved
  33. \  in the dictionary.  Then, as long as you just want to UPDATE
  34. \  to those directories, just type in UPD.
  35. \
  36. \  UPD also uses the options that were specified in the previous
  37. \  UPDATE command.
  38. \
  39. \
  40. \ 00001 27-apr-91 mdh - Added copying of source file datestamp
  41. \                     - changed version stamp
  42. \                     - revised output query format
  43. \ 00002 10-mar-91 mdh - increment version # due to fix in setdate.f  (1.3)
  44. \ ----- 10-sep-91 mdh - added '-all' recursive option (1.3+)
  45. \ 00003 21-sep-91 mdh - added printing of directory  (1.4)
  46. \ 00004 09-dec-91 mdh - fixed problem with cancel  (1.5)
  47. \ 00005 15-jan-92 mdh - added -WARN <date> option  (1.6)
  48.  
  49. max-inline @   6 max-inline !
  50.  
  51. exists? getmodule
  52. .if     getmodule includes
  53. .then
  54.  
  55. .need Enable_Cancel
  56.   cr ." If you want to clone UPDATE, the CLONE program must be"
  57.   cr ." compiled FIRST.  This is not currently the case." cr
  58.   cr ." Do you want to compile CLONE now" y/n cr
  59.   .IF
  60.      include cl:topfile
  61.   .ELSE
  62.      ." NOTE: If you later compile CLONE on top of UPDATE, the CANCEL" cr
  63.      ."       keys (CTRL-C,D,E,F) will not work in CLONEd programs." cr cr
  64.      variable Enable_Cancel
  65.      : CancelKey?  0 ;
  66.   .THEN
  67. .then
  68.  
  69. include? LIBRARIES_DOS_H ji:libraries/dos.j
  70. include? Lock() ju:dos-support
  71. include? setdate ju:setdate.f   \ 00001
  72. include? dynamicstack ju:stackutils
  73.  
  74. anew task-Update.f
  75.  
  76. \ ****************************  the program  *****************************
  77.  
  78. variable UPD_CANCELED   UPD_CANCELED off   \ 00004
  79.  
  80. variable SRCFIB   \ pointers to FileInfoBlocks
  81. variable DESTFIB
  82.  
  83. variable SRCDIR$   40 allot   \ buffers for pathnames
  84. variable DESTDIR$  40 allot
  85.  
  86. " wp:"   srcdir$ $move
  87. " wp2:" destdir$ $move
  88.  
  89. variable SRCLOCK  \ storage
  90. variable DESTLOCK
  91. variable PREVLOCK
  92.  
  93. variable SRCFILE  \ for storing actual file pointers
  94. variable DESTFILE
  95.  
  96. variable UPDBUFFSIZE    10 1024 * updbuffsize !
  97. variable UPDSizeMode \ qualifies a copy operation on size or date basis
  98. variable UPDListOnly
  99. variable UPDNoAsk
  100. variable UPDExists
  101. variable UPDRecurse
  102. variable DoANSI
  103. variable #Nests
  104. variable UPDWarn
  105.  
  106. 128 Dynamicstack Locks
  107. 128 DynamicStack FIBs
  108.  32 DynamicStack DirNames
  109.  
  110. \ create dirname 64 allot
  111. \ variable NameShown
  112.  
  113.  
  114. \ ----------------------- Interpret date string ------------------------
  115.  
  116. decimal
  117.            60    constant TICKSperSEC
  118.            60    constant SECperMIN
  119. SECperMIN  60 *  constant SECperHR
  120. SECperHR   24 *  constant SECperDAY
  121. SECperDAY 365 *  constant SECperYR
  122.  
  123. variable day
  124. variable month
  125. variable year
  126. variable totalsecs
  127.  
  128. create WarnString   16 allot
  129.  
  130. DateStamp WarnDate
  131.  
  132. : months  0" janfebmaraprmayjunjulaugsepoctnovdec"   ;
  133.  
  134.  
  135. 12 array numdays
  136.  
  137. 31  0 numdays !     28  1 numdays !     31  2 numdays !
  138. 30  3 numdays !     31  4 numdays !     30  5 numdays !
  139. 31  6 numdays !     31  7 numdays !     30  8 numdays !
  140. 31  9 numdays !     30 10 numdays !     31 11 numdays !
  141.  
  142.  
  143. : month>num  ( &3chars -- num , 1-based, 0 means not found )
  144.   months   0   12 0
  145.   DO
  146.      ( -- &3chars months num )   2 pick 3  3 pick 3  match?
  147.      IF
  148.         drop ( the zero )   i 1+   leave
  149.      ELSE
  150.         swap  3 +  swap
  151.      THEN
  152.   LOOP
  153.   nip nip
  154. ;
  155.  
  156.  
  157. 0 .if
  158. : aBCDLeap  ( yr -- flag )
  159.   dup  -4 ashift  10 *
  160.   swap  $ 0f and  3 and
  161.   +     0=
  162. ;
  163. .then
  164.  
  165.  
  166. : aLeap  ( yr -- flag )  3 and  0=   ;
  167.  
  168.  
  169. variable err#
  170.  
  171. : BadArgs?   ( flag -- )
  172.   IF
  173.      err# @ ?dup
  174.      IF
  175.         >newline ." error " .
  176.      THEN
  177.      >newline ." Error in date string" cr decimal quit
  178.   THEN
  179. ;
  180.  
  181.    
  182. : SetWarnDate  ( -- , <date> )  \ QUITs if invalid format
  183.   day   off
  184.   month off
  185.   year  off
  186.   err#  off
  187. \ /* Interpret arguments from input stream ... dd-mmm-yy ... */
  188. \
  189.   bl word drop  decimal
  190. \ /* Get day... */
  191.   0. here    convert
  192.   ( -- lo hi adr )         dup c@  ascii - -
  193. \ 1 err# !
  194.   ( -- lo hi adr flag )    3 pick  1 <  OR  BadArgs?
  195.   1+ >r  drop  day !
  196. \
  197. \     /* finish err check on day after month & yr is known */
  198. \ /* Get month... */
  199.   ( -- )
  200. \ 2 err# !
  201.   r@ month>num  dup 0=  r@ 3 + c@ ascii - - or  ( -- num flag )  BadArgs?
  202.   month !
  203. \ /* Get year... */
  204.   0. r> 3 +   convert
  205.   ( -- lo hi adr )         dup c@ bl -
  206. \ 3  err# !
  207.   ( -- lo hi adr flag )    3 pick 78 <  OR  BadArgs?
  208.   2drop  year !
  209. \ /* finish err check on 'days' ... */
  210. \
  211.   year @ aLeap   month @ 2 =  AND
  212.   IF
  213. \ 4 err# !
  214.      day @ 29 >  BadArgs?
  215.   ELSE
  216.      day @ ( -4 ashift  10 *   day @ $ 0f and + )
  217. \ 5 err# !
  218.      month @ 1- numdays @  >  BadArgs?
  219.   THEN
  220.  
  221. \ /* the digits have been loaded in...convert to Amiga 'seconds' */
  222. \
  223. \ /* calc #seconds to Jan 1 of this year... */
  224.   totalsecs off
  225.   year @  78
  226.   DO
  227.      SECperYR totalsecs +!
  228.      i aleap
  229.      IF
  230.         SECperDAY totalsecs +!
  231.      THEN
  232.   LOOP
  233. \ /* calc additional secs to begin of this month... */
  234.   month @ 1-   0
  235.   DO
  236.      i numdays @  SECperDAY *  totalsecs +!
  237.   LOOP
  238.   month @ 2 >  year @ aLeap  and
  239.   IF
  240.      SECperDAY totalsecs +!
  241.   THEN
  242. \ /* calc tot secs at midnite ...  */
  243.   day @ 1-  SECperDAY *  totalsecs +!
  244. \ /* calc total secs at start of this hour... */
  245. \ hour @  SECperHR *  totalsecs +!
  246. \ /* calc total secs to start of this minute... */
  247. \ min @  SECperMIN *  totalsecs +!
  248. \ /* add in extra seconds... */
  249. \ sec @  totalsecs +!
  250. \
  251.   totalsecs @  SECperDAY /mod  WarnDate ..! ds_days
  252.   ( -- secs )  SECperMIN /mod  WarnDate ..! ds_Minute
  253.   ( -- secs )  TICKSperSEC *   WarnDate ..! ds_Tick
  254.   here WarnString $move
  255. ;
  256.  
  257.  
  258. \ ------------------- End of Interpret date string ---------------------
  259.  
  260.  
  261.  
  262. .need CreateDir()
  263. : CreateDir()  ( 0name -- lock , 0=fail )
  264.  >abs call dos_lib CreateDir
  265. ;
  266. .then
  267.  
  268. : ALLOCFIBS  ( -- , allocation insures long-word alignment )
  269.   MEMF_CLEAR  sizeof() FileInfoBlock   2dup
  270.   allocblock?    srcfib !
  271.   allocblock?   destfib !
  272. ;
  273.  
  274.  
  275. : @FREEFIB  ( var-addr -- )
  276.   dup @ ?dup
  277.   IF   freeblock  ( -- var-addr )  dup off
  278.   THEN drop
  279. ;
  280.  
  281.  
  282. : FREEFIBS   ( -- , give back both FileInfoBlocks )
  283.   srcfib  @freefib
  284.   destfib @freefib
  285. ;
  286.  
  287.  
  288. : GETLOCK  ( forth-$addr -- lock OR 0 )
  289.   ACCESS_READ  $Lock()
  290. ;
  291.  
  292.  
  293. : @UNLOCK  ( var-addr -- , fetch and unlock anything there )
  294.   dup @ ?dup
  295.   IF   UnLock()  ( -- var-addr )   dup off
  296.   THEN drop
  297. ;
  298.  
  299.  
  300.  
  301. : CLEANUP  ( -- , get rid of anything & everything )
  302. \
  303. \ restore any previously selected directory...
  304. \
  305.   prevlock dup @ ?dup
  306.   IF    CurrentDir() drop
  307.   THEN  off
  308. \
  309. \ give back everything else...
  310. \
  311.   LocksVAR @
  312.   IF
  313.      Locksbase freecell  0
  314.      DO
  315.         Locksbase pop Unlock()
  316.      LOOP
  317.      LocksVAR Freestack
  318.   THEN
  319.   FIBsVAR @
  320.   IF
  321.      FIBsbase freecell  0
  322.      DO
  323.         FIBsbase pop freeblock
  324.      LOOP
  325.      FIBsVAR Freestack
  326.   THEN
  327.   srclock  @unlock
  328.   destlock @unlock
  329.   freefibs
  330.   DirNamesVAR @
  331.   IF
  332.      DirNamesBase dup freecell 2/ 0
  333.      DO
  334.         cell+ @ freeblock  cell+
  335.      LOOP
  336.      drop  DirNamesVAR freestack
  337.   THEN
  338.   
  339. ;
  340.  
  341.  
  342.  
  343. : OPENED?  ( 0name fileptr? -- 0name fileptr )
  344.   ?dup 0=
  345.   IF    cleanup ." Can't open " 0count type quit
  346.   THEN  dup markfclose
  347. ;
  348.  
  349. : UPDYesOrNo  ( -- true = yes )
  350.   ." (Y)es or (N)o? "  key ( dup emit cr \ no good from CLI )
  351.   out off   ?terminal
  352.   IF
  353.      key drop
  354.   ELSE
  355.      dup emit cr
  356.   THEN
  357.   $ 20 or  ascii y =
  358. ;
  359.  
  360. : BuildDirNameAtPad  ( upto# -- )
  361.   pad off
  362.   DirNamesBase dup freecell 2/   ( -- #upto base #names )
  363.   rot 1+ min  0
  364.   DO
  365.      cell+ dup @ count pad $append
  366.      " /" count pad $append
  367.      cell+
  368.   LOOP
  369.   drop
  370. ;
  371.  
  372. : OutPutName  ( addr cnt -- )
  373.   DoANSI @
  374.   IF
  375.      inverse \ italic
  376.   THEN
  377.   type
  378.   DoANSI @
  379.   IF
  380.      plain
  381.   THEN
  382. ;
  383.  
  384. : PrintAllNames  ( -- )
  385.   DirNamesBase dup freecell 2/   ( -- base #names )  0
  386.   DO
  387.      dup @ 0=
  388.      IF
  389.         ( -- &flag )  >newline  i 3 * spaces
  390.         i BuildDirNameAtPad pad count OutputName cr   dup on
  391.      THEN
  392.      [ 2 cells ] literal +
  393.   LOOP
  394.   drop
  395. ;
  396.  
  397. : <COPYIT>  ( -- , srcfib holds name )
  398.   PrintAllNames
  399. \
  400. \ Allocate a buffer for filexfer...
  401. \
  402.   UPDListOnly @ 0=
  403.   IF
  404.      MEMF_CLEAR  updbuffsize @  allocblock ?dup 0=
  405.      IF    cleanup  ." Insufficient memory available" quit
  406.      THEN  dup markfreeblock  >r
  407.   THEN
  408. \
  409. \ Open the SRC file...
  410. \
  411.   #nests @ 3 * spaces
  412. \
  413.   srclock @ CurrentDir() drop
  414.   srcfib @ .. fib_Filename      ( -- 0name )
  415.   UPDListOnly @ 0=
  416.   IF
  417.      dup  0fopen opened?  srcfile !
  418.      \
  419.      \ Open the DEST file...
  420.      \
  421.      destlock @ CurrentDir() drop dup new 0fopen opened? destfile !
  422.      \
  423.      \ Announce...
  424.      \
  425.      ( -- 0name )   ." -- Copying "
  426.   ELSE
  427.      ." -- Would copy "
  428.   THEN
  429.   0count type  cr   ( -- )
  430.   UPDListOnly @ 0=
  431.   IF
  432.      \
  433.      \ Copy...
  434.      \
  435.      1  ( dummy value )
  436.      BEGIN
  437.            dup 0>
  438.            IF   drop   srcfile @ ( fptr )  r@ ( addr )
  439.                 dup sizemem  FREAD dup 0>
  440.            ELSE FALSE
  441.            THEN
  442.      WHILE
  443.            destfile @    r@   rot  FWRITE  dup 0<
  444.            IF   ." Error while writing." cr
  445.            THEN
  446.      REPEAT drop
  447.      \
  448.      \ close files, give back memory...
  449.      \
  450.      srcfile  @ dup unmarkfclose  fclose
  451.      destfile @ dup unmarkfclose  fclose
  452.      r> dup unmarkfreeblock  freeblock
  453.      \
  454.      \ clone protection
  455.      \
  456.      destlock @ CurrentDir() drop
  457.      srcfib @ dup .. fib_Filename ( -- srcfib@ &0name )  2dup ( added 00001)
  458.      >abs swap ..@ fib_Protection  call dos_lib SetProtection drop
  459.      \
  460.      \ clone date  00001
  461.      \
  462.      ( MUST be selected to 'destlock, done just above )
  463.      ( -- srcfib@ &0name )  swap .. fib_Date  SetDate drop
  464.      \
  465.   THEN
  466. ;
  467.  
  468.  
  469. variable Found>
  470.  
  471. : DateCompare  ( n1 n2 -- flag , set variables & return TRUE if = )
  472.   -  ?dup
  473.   IF
  474.      Found>  swap  0<
  475.      IF
  476.         off
  477.      ELSE
  478.         on
  479.      THEN
  480.      false
  481.   ELSE
  482.      Found> off  true
  483.   THEN
  484. ;
  485.  
  486.  
  487. : DateStamp>  ( datestamp_struct1 datestamp_struct2 -- flag )
  488. \
  489. \ return non-zero if strct1 is later than struct2
  490. \
  491.   over ..@ ds_Days   over ..@ ds_Days  DateCompare
  492.   IF
  493.      over ..@ ds_Minute   over ..@ ds_Minute  DateCompare
  494.      IF
  495.         over ..@ ds_Tick   over ..@ ds_Tick  DateCompare  drop
  496.      THEN
  497.   THEN
  498.   2drop  Found> @
  499. ;
  500.  
  501. variable NUMCOPIED
  502.  
  503. : COPYIT?  ( -- , SRCFIB is set to a directory )
  504.   \
  505.   \ Create a default TRUE flag on the ret stack...
  506.   \
  507.   TRUE >r
  508.   \
  509.   \ Does it exist in the DEST dir?
  510.   \
  511.   destlock @ CurrentDir() drop
  512.   srcfib @ .. fib_Filename  ACCESS_WRITE  Lock()  -dup
  513.   IF
  514.      \
  515.      \ Yes, is it not a FILE that meets the criteria? ( -- dest??Lock )
  516.      \
  517.      dup  destfib @  Examine()   ( -- dlock flag )
  518.      swap UnLock()
  519.      IF
  520.         destfib @ ..@ fib_DirEntryType  0<   ( -- flag )
  521.         dup 0= >r   ( true if it is a directory )
  522.         UPDSizeMode @
  523.         IF
  524.            \
  525.            \ Check size too...
  526.            \
  527.            destfib @ ..@ fib_Size  ( -- flag destsize )
  528.            srcfib  @ ..@ fib_Size  =
  529.         ELSE
  530.            \
  531.            \ Check if the date is later...
  532.            \
  533.            srcfib @ .. fib_Date  destfib @ .. fib_Date
  534.            ( -- flag &datesrc &datedest )  DateStamp> 0=
  535.         THEN
  536.         AND  r> OR
  537.         UPDWarn @
  538.         IF
  539.            srcfib  @ .. fib_Date  WarnDate  DateStamp>
  540.            destfib @ .. fib_Date  WarnDate  DateStamp>   and
  541.            IF
  542.               PrintAllNames
  543.               >newline ." WARNING: Both '"
  544.               srcfib @ .. fib_Filename  0count type
  545.               ." ' files are newer than " WarnString $type cr
  546.               drop true
  547.            THEN
  548.         THEN
  549.         \ Don't copy?
  550.         IF
  551.            \
  552.            \ If here, do NOT copy, cancel the default flag...
  553.            \ DEST object is either a dir, or doesn't qualify.
  554.            \
  555.            r> drop  FALSE >r
  556.         THEN
  557.      THEN
  558.   ELSE
  559.      UPDExists @
  560.      IF
  561.         rdrop  false >r
  562.      THEN
  563.   THEN r>
  564.   IF
  565.      <COPYIT>  1 NUMCOPIED +!
  566.   THEN
  567. ;
  568.  
  569. .NEED .COMMAND
  570. : .COMMAND ( -- <name> )
  571.     >in @
  572.     >in off
  573.     bl word $type
  574.     >in !
  575. ;
  576. .THEN
  577.  
  578. : UpdateLocks  ( --, srclock+destlock set & fibs alloc'ed )
  579. \
  580. \ Examine the source directory (init the fib)...
  581. \
  582.   srclock @   srcfib @   Examine()  0=
  583.   IF    cleanup  ." Can't examine SRCDIR!" cr quit
  584.   THEN
  585. \
  586. \ make sure it is a directory...
  587. \
  588.   srcfib @  ..@ fib_DirEntryType 0<
  589.   IF    cleanup  ." SOURCE must be a directory!" cr quit
  590.   THEN
  591. \
  592. \ print informative message 00003
  593. \
  594.   \ allocate an area
  595.   srcfib @ .. fib_Filename  0count  ( adr cnt )
  596.   dup 2+   MEMF_CLEAR  swap allocblock  ?dup 0=
  597.   IF
  598.      >newline ." Insufficient available memory" cr cleanup quit
  599.   THEN
  600.   ( -- text cnt memblk )
  601.   0 DirNames +stack   ( not shown yet )
  602.   dup>r DirNames +stack  r@ off  r@ $append  r> +null
  603. \
  604. \ now process each file in the SRC directory...
  605. \
  606.   BEGIN
  607.      CancelKey?     UPD_CANCELED @  or \ 00004
  608.      IF
  609.         UPD_CANCELED @ 0=   \ 00004
  610.         IF
  611.            >newline .command ."  canceled" cr  UPD_CANCELED on \ 00004
  612.         THEN
  613.         false
  614.      ELSE
  615.         srclock @  srcfib @  ExNext()  ( -- flag )
  616.      THEN
  617.   WHILE
  618.      \
  619.      \ Make sure it is a file and not a dir...
  620.      \
  621.      srcfib @ ..@ fib_DirEntryType 0<  ( neg if a file )
  622.      IF
  623.         copyit?
  624.      ELSE
  625.         \
  626.         \ OK, we've found another dir...save locks, fibs,
  627.         \ set new locks, alloc new fibs, recurse, then restore
  628.         \ upon return
  629.         \
  630.         UPDRecurse @
  631.         IF
  632.            \ does the dir exist in the destdir?
  633.            srcfib  dup @ dup>r FIBs +stack off
  634.            destfib dup @ dup>r FIBs +stack off    AllocFIBs
  635.            srclock @ >r
  636.            destlock @ dup>r   CurrentDir() drop
  637.            ( -r- SFIB DFIB SLK0 DLK0 )
  638.            3 rpick ( SFIB ) .. fib_Filename  ACCESS_READ  Lock() ?dup 0=
  639.            IF
  640.               UPDExists @
  641.               IF
  642.                  0
  643.               ELSE
  644.                  UPDListOnly @
  645.                  IF
  646.                     PrintAllNames  >newline
  647.                     #nests @ 1+ 3 * spaces  \ ." DIRECTORY "
  648.                     #nests @ BuildDirNameAtPad
  649.                     3 rpick ( SFIB ) .. fib_Filename 0count pad $append
  650.                     " /" count pad $append  pad count OutputName
  651.                     ."  would be created & duplicated" cr  0
  652.                  ELSE
  653.                     \ create the dir, return the lock
  654.                     3 rpick ( SFIB ) .. fib_Filename CreateDir() dup 0=
  655.                     IF
  656.                        >newline ." Can't create subdirectory" cr
  657.                     ELSE
  658.                        Unlock()
  659.                        3 rpick .. fib_Filename  ACCESS_READ  Lock()
  660.                     THEN
  661.                  THEN
  662.               THEN
  663.            THEN
  664.            ?dup IF
  665.               \ it exists, is it a dir?
  666.               destlock @ Locks +stack
  667.               dup destlock !   destfib @  Examine()   ( -- flag )
  668.               IF
  669.                  destfib @ ..@ fib_DirEntryType 0<  ( neg if file )
  670.                  IF
  671.                     >newline ." Source is directory, Destination is file: "
  672.                     destfib @ .. fib_Filename 0count type  cr
  673.                  ELSE
  674.                     \
  675.                     \ the directory exists, lock srcdir
  676.                     srclock @ CurrentDir() drop
  677.                     3 rpick .. fib_Filename  ACCESS_READ  Lock() ?dup
  678.                     IF
  679.                        dup CurrentDir() drop
  680.                        srclock @ Locks +stack
  681.                        srclock !   1 #nests +!
  682.                        recurse    -1 #nests +!
  683.                        1 rpick  CurrentDir() drop
  684.                        srclock @ Unlock()
  685.                        Locksbase pop drop
  686.                     THEN
  687.                  THEN
  688.               THEN
  689.               destlock @ Unlock()
  690.               Locksbase pop drop
  691.            THEN
  692.            r> destlock !
  693.            r> srclock !
  694.            FreeFIBs  r> destfib !  r> srcfib !
  695.            FIBsbase pop drop  FIBsbase pop drop
  696.         THEN
  697.      THEN
  698.   REPEAT
  699.   DirNamesBase pop freeblock   DirNamesBase pop drop
  700. ;
  701.  
  702. : UPD  ( -- , SRCDIR and DESTDIR should point to two directory PATHnames )
  703.   NUMCOPIED off  UPD_CANCELED off \ 00004
  704.   allocfibs
  705. \
  706. \ Get locks on both directories...
  707. \
  708.   srcdir$  getlock  ?dup
  709.   IF    srclock !
  710.   ELSE  cleanup  ." Can't find source directory" cr quit
  711.   THEN
  712.   destdir$ getlock  ?dup 0=
  713.   IF
  714.      destdir$ $type ."  doesn't exist."  UPDListOnly @
  715.      IF
  716.         cr cleanup quit
  717.      ELSE
  718.         ."  Create it? " UPDYesOrNo 0=
  719.         IF
  720.            cleanup quit
  721.         THEN
  722.         destdir$ count >dos  dos0 CreateDir() ?dup 0=
  723.         IF
  724.            ." Error creating " destdir$ $type cr cleanup quit
  725.         THEN
  726.         Unlock()  dos0  ACCESS_READ  Lock()
  727.      THEN
  728.   THEN
  729.   destlock !
  730. \
  731. \ Set one-of-em as CURRENT directory (just to get the 'prevlock')...
  732. \
  733.   srclock @  CurrentDir()  prevlock !
  734.   \
  735.   UpdateLocks
  736.   \
  737.   NumCopied @ dup 0=
  738.   IF
  739.      ." No "
  740.   ELSE
  741.      dup .
  742.   THEN
  743.   ." file"  1-
  744.   IF
  745.      ascii s emit
  746.   THEN
  747.   UPDListOnly @
  748.   IF
  749.      ."  would be"
  750.   THEN
  751.   ."  copied." cr
  752. \
  753. \ that's all folks...
  754. \
  755.   cleanup
  756. ;
  757.  
  758. variable numspaces
  759.  
  760. : .spaces   numspaces @ spaces ;
  761.  
  762. : .HELP ( -- )
  763.     cr
  764.     ." Usage: " .command     out @ 16 + numspaces !
  765.     ."  FromDir ToDir [-date|-size -list -noask -both"  cr
  766.           .spaces   ." -all -off -warn <dd-mmm-yy>]"  cr cr
  767. \
  768.     ."  -date = Copy if FromDir/file is NEWER than ToDir/file (DEFAULT)" cr
  769.     ."  -size = Copy if FromDir/file is DIFFERENT SIZE than ToDir/file" cr
  770.     ."  -list = Do NOT COPY, just LIST files that would be copied" cr
  771.     ."  -noask= Do NOT PROMPT for user verification" cr
  772.     ."  -both = Update only which already exists in BOTH directories" cr
  773.     ."  -all  = Update all subdirectories and their contents" cr
  774.     ."  -off  = Turn off ansi highlighting for directory names" cr
  775.     ."  -warn = Warn if both files are newer than <date> (don't copy)" cr
  776.     ."          for example:   -warn 4-jul-91"   cr cr
  777. \
  778.     ."  CTRL-C, D, E or F will abort the program" cr
  779.     ."  Any portion of an option qualifies it  (examples: -n -bo)" cr
  780. ;
  781.  
  782. : UPDhelp?  here c@ 0=  here 1+ c@ ascii - =  OR
  783.   IF
  784.     .help  quit
  785.   THEN
  786. ;
  787.  
  788. : IsIT?  ( string -- flag )
  789.   >r   here count   r> 1+ text=?
  790. ;
  791.  
  792. variable DateSpecked
  793.  
  794. : DateSizeErr  ( -- )
  795.   >newline  ." ERROR: -DATE and -SIZE are mutually exclusive..." cr
  796.   ."        Only one may be specified (default is -DATE)" cr  quit
  797. ;
  798.  
  799. : SetUPDMode  ( -- , parses remainder of line for options )
  800.   UPDSizeMode off   \ default: -DATE mode
  801.   UPDListOnly off   \ default: copy the files
  802.   UPDNoAsk    off   \ default: let user verify
  803.   UPDExists   off   \ default: copy all files
  804.   UPDRecurse  off   \ default: stay at this level
  805.   DoANSI      on    \ default: display highlight for dirnames
  806.   UPDWarn     off
  807.   #nests off
  808.   BEGIN
  809.      bl word c@
  810.   WHILE
  811.      " -SIZE"  IsIt?
  812.      IF
  813.         DateSpecked @  IF  DateSizeErr  THEN
  814.         UPDSizeMode on
  815.      ELSE
  816.         " -DATE"  IsIt?
  817.         IF
  818.            DateSpecked on  UPDSizeMode @  IF  DateSizeErr  THEN
  819.            UPDSizeMode off
  820.         ELSE
  821.            " -LIST"  IsIt?
  822.            IF
  823.               UPDListOnly on
  824.            ELSE
  825.               " -NOASK"  IsIt?
  826.               IF
  827.                  UPDNoAsk on
  828.               ELSE
  829.                  " -BOTH"  IsIt?
  830.                  IF
  831.                     UPDExists  on
  832.                  ELSE
  833.                     " -ALL" IsIt?
  834.                     IF
  835.                        UPDRecurse on
  836.                     ELSE
  837.                        " -OFF" IsIt?
  838.                        IF
  839.                           DoANSI off
  840.                        ELSE
  841.                           " -WARN" IsIt?
  842.                           IF
  843.                              SetWarnDate  UPDWarn on
  844.                           ELSE
  845.                              .help quit
  846.                           THEN
  847.                        THEN
  848.                     THEN
  849.                  THEN
  850.               THEN
  851.            THEN
  852.         THEN
  853.      THEN
  854.   REPEAT
  855. ;
  856.  
  857. : .pathname  ( $name -- )
  858.   ascii " emit  $type  ascii " emit
  859. ;
  860.  
  861. .NEED .COMMAND
  862. : .COMMAND ( -- <name> )
  863.     >in @
  864.     >in off
  865.     bl word $type
  866.     >in !
  867. ;
  868. .THEN
  869.  
  870. : UPDATE  ( <srcdir> <destdir> )
  871.   >newline .command ."  V1.6 by Mike Haas  (written in JForth)"
  872.   out @ dup>r cr  0 do  ascii = emit loop cr  \ 00001 00002
  873.   fileword  UPDHelp?  dup c@ 1+  40 max   srcdir$  swap  move
  874.   fileword  UPDHelp?  dup c@ 1+  40 max  destdir$  swap  move
  875.   ' cleanup is errorcleanup   \ for cloned images
  876.   SetUPDMode
  877.   UPDNoAsk @ 0=
  878.   IF
  879.      \ 00001, revised messages
  880.      \
  881.      UPDListOnly @
  882.      IF
  883.         ." List files that would be copied"
  884.      ELSE
  885.         ." Copy files"
  886.      THEN
  887.      cr cr
  888.      ."     FROM:   "  srcdir$ .pathname cr
  889.      ."       TO:   " destdir$ .pathname cr cr
  890.      ." IF "   UPDExists @
  891.      IF
  892.         ." they exist in both places AND "  cr  \ cr ." places AND "
  893.      THEN
  894.      UPDSizeMode @
  895.      IF
  896.         ." they are different in size?"
  897.      ELSE
  898.         ." the file in the FROM: directory is newer?"
  899.      THEN
  900.      cr
  901.      UPDRecurse @
  902.      IF
  903.         ." (Including All Subdirectories)" cr
  904.      THEN
  905.      UPDYesOrNo
  906.      IF
  907.         r@ 0 do  ascii = emit loop cr
  908.         UPD
  909.      THEN
  910.      begin ?terminal
  911.      while key drop
  912.      repeat
  913.   ELSE
  914.      UPD
  915.   THEN
  916.   >newline  rdrop
  917. ;
  918.  
  919.  
  920. max-inline !
  921.